#!/bin/bash

###########################################################################
# Nash!Com Domino Docker Management Script                                #
# Version 1.0.9 21.12.2020                                                #
#                                                                         #
# (C) Copyright Daniel Nashed/NashCom 2020                                #
# Feedback domino_unix@nashcom.de                                         #
#                                                                         #
# Licensed under the Apache License, Version 2.0 (the "License");         #
# you may not use this file except in compliance with the License.        #
# You may obtain a copy of the License at                                 #
#                                                                         #
#      http://www.apache.org/licenses/LICENSE-2.0                         #
#                                                                         #
# Unless required by applicable law or agreed to in writing, software     #
# distributed under the License is distributed on an "AS IS" BASIS,       #
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.#
# See the License for the specific language governing permissions and     #
# limitations under the License.                                          #
###########################################################################

SCRIPT_NAME=$0
FULL_SCRIPT_NAME=$0
SCRIPT_DIR_NAME=`dirname $SCRIPT_NAME`
FULL_SCRIPT_DIR_NAME=`dirname $FULL_SCRIPT_NAME`
CONFIG_TEMPLATE_FILE=$FULL_SCRIPT_DIR_NAME/config_`basename $SCRIPT_NAME | awk -F "docker_" '{print $2}'`
PARAM1=$1
PARAM2=$2
PARAM3=$3

# Default Configuration parameters overwritten by config file if available in same directory

DOCKER_CONTAINER=
DOCKER_IMAGE_NAME=
DOCKER_IMAGE_VERSION=
DOCKER_IMAGE_RELEASE_DATE=
DOCKER_FILE=

DOMINO_SHUTDOWN_TIMEOUT=60
DOCKER_HOSTNAME=
# DOCKER_NETWORK_NAME=host
# DOCKER_SPECIAL_OPTIONS="--ip 172.17.0.1"
DOCKER_PORTS="-p 1352:1352 -p 80:80 -p 443:443"
DOCKER_VOLUMES=

# Environment file is used for first container start (run) to pass setup parameters
DOCKER_ENV_FILE=

# Update CentOS while building the image
LinuxYumUpdate=yes

# Special WGET options used for all downloads

#SPECIAL_WGET_ARGUMENTS="--no-check-certificate"

#SPECIAL_CURL_ARGS="--insecure"

# Configure software download location.
# You can either use your own software repository remotely.
# Or use a local software image hosted via NGINX temporary image.
# By default NIGX is used hosting software from the local "software" directory.

#DOWNLOAD_FROM=http://192.168.1.1

# Configuration for NGINX container for software download
SOFTWARE_USE_NGINX=0
SOFTWARE_DIR=$PWD/software
SOFTWARE_PORT=7777
SOFTWARE_CONTAINER=ibmsoftware

# Default config directory. Can be overwritten by environment 
if [ -z "$DOMINO_DOCKER_CFG_DIR" ]; then
  DOMINO_DOCKER_CFG_DIR=/local/cfg
fi

DOCKER_SCRIPT_VERSION=1.0.8

# Get configuration from config file
# First check in global config directory before checking in current directory

CONFIG_FILE=$DOMINO_DOCKER_CFG_DIR/config_`basename $SCRIPT_NAME | awk -F "docker_" '{print $2}'`
if [ -e "$CONFIG_FILE" ]; then
  echo "(Using config file $CONFIG_FILE)"
  . $CONFIG_FILE
else
  CONFIG_FILE=$SCRIPT_DIR_NAME/config_`basename $SCRIPT_NAME | awk -F "docker_" '{print $2}'`
  if [ -e "$CONFIG_FILE" ]; then
    echo "(Using config file $CONFIG_FILE)"  
    . $CONFIG_FILE
  fi
fi

# check if environment file exists in config dir, else use local dir
if [ -z "$DOCKER_ENV_FILE" ]; then
  DOCKER_FULL_ENV_FILE=
else
  if [ -r "$DOMINO_DOCKER_CFG_DIR/$DOCKER_ENV_FILE" ]; then
    DOCKER_FULL_ENV_FILE="$DOMINO_DOCKER_CFG_DIR/$DOCKER_ENV_FILE"
  else
    DOCKER_FULL_ENV_FILE="$DOCKER_ENV_FILE"
  fi
fi

DOCKER_IMAGE_BUILD_VERSION=$DOCKER_IMAGE_VERSION

# Special configuration

BUILDTIME=`date +"%d.%m.%Y %H:%M:%S"`

#DOCKER_TAG_LATEST="$DOCKER_IMAGE_NAME:latest"

if [ -z "$DOWNLOAD_FROM" ]; then
  if [ -z "$SOFTWARE_USE_NGINX" ]; then
    SOFTWARE_USE_NGINX=1
  fi
fi

DOCKER_IMAGE_NAMEVERSION=$DOCKER_IMAGE_NAME:$DOCKER_IMAGE_BUILD_VERSION

if [ -z "$DOCKER_IMAGE" ]; then
  if [ -z "$DOCKER_TAG_LATEST" ]; then

    DOCKER_IMAGE=$DOCKER_IMAGE_NAMEVERSION
    DOCKER_TAG_LATEST_CMD=""
  else
    DOCKER_IMAGE=$DOCKER_TAG_LATEST
    DOCKER_TAG_LATEST_CMD="-t $DOCKER_TAG_LATEST"
  fi
fi

if [ -z "$EDIT_COMMAND" ]; then
  EDIT_COMMAND="vi"
fi

# Get OS type
LARCH=`uname`

print_delim ()
{
  echo "------------------------------------------------------------------------------------------"
}

config_warnings ()
{
  DOCKER_STORAGE_DIRVER=`$DOCKER_CMD info 2>/dev/null |grep "Storage Driver: " | cut -d ":" -f2 | awk '{ sub(/^[ ]+/, ""); print }'`

  if [ "$DOCKER_STORAGE_DIRVER" = "overlay" ]; then 
    echo
    echo "Warning: It's strongly recommended to use the 'Overlay2' driver!"
  fi
  
  if [ ! -z "$DOCKER_CONTAINER_IMAGE_ID" ]; then
    if [ ! "$DOCKER_CONTAINER_IMAGE_ID" = "$DOCKER_IMAGE_ID" ]; then
      echo
      echo "Info: New Image Version available!"
    fi
  fi
  
  return 0
}

check_version ()
{
  count=1

  while true
  do
    VER=`echo $1|cut -d"." -f $count`
    CHECK=`echo $2|cut -d"." -f $count`

    if [ -z "$VER" ]; then return 0; fi
    if [ -z "$CHECK" ]; then return 0; fi

    if [ $VER -gt $CHECK ]; then return 0; fi
    if [ $VER -lt $CHECK ]; then
      echo "Warning: Unsupported $3 version $1 - Must be at least $2 !"
      sleep 1
      return 1
    fi

    count=`expr $count + 1`
  done

  return 0
}

check_docker_environment()
{
  DOCKER_MINIMUM_VERSION="18.09.0"
  PODMAN_MINIMUM_VERSION="1.0.5"

  if [ -x /usr/bin/podman ]; then
    if [ -z "$USE_DOCKER" ]; then
      # podman environment detected
      DOCKER_CMD=podman
      DOCKER_ENV_NAME=Podman
      DOCKER_VERSION_STR=`podman version`
      DOCKER_VERSION=`echo $DOCKER_VERSION_STR | cut -d" " -f2`
      check_version "$DOCKER_VERSION" "$PODMAN_MINIMUM_VERSION" "$DOCKER_CMD"
      return 0
    fi
  fi

  if [ -z "$DOCKERD_NAME" ]; then
    DOCKERD_NAME=dockerd
  fi

  if [ -z "$DOCKER_CMD" ]; then
    DOCKER_CMD=docker
  fi

  DOCKER_ENV_NAME=Docker

  # check docker environment
  DOCKER_VERSION_STR=`docker -v`
  DOCKER_VERSION=`echo $DOCKER_VERSION_STR | cut -d" " -f3|cut -d"," -f1`

  check_version "$DOCKER_VERSION" "$DOCKER_MINIMUM_VERSION" "$DOCKER_CMD"

  # some commands are ok, when dockerd isn't startred
  if [ -z "$1" ]; then return 0; fi
  if [ "$1" = "config" ]; then return 0; fi
  if [ "$1" = "cfg" ]; then return 0; fi

  # Use sudo for docker command if not root on Linux

  if [ `uname` = "Linux" ]; then
    if [ ! "$EUID" = "0" ]; then
      if [ "$DOCKER_USE_SUDO" = "no" ]; then
        echo "Docker needs root permissions on Linux!"
        exit 1
      fi
      DOCKER_CMD="sudo $DOCKER_CMD"
    fi
  fi

  return 0
}

print_runtime()
{
  echo
  
  # the following line does not work on OSX 
  # echo "Completed in" `date -d@$SECONDS -u +%T`
 
  hours=$((SECONDS / 3600))
  seconds=$((SECONDS % 3600))
  minutes=$((seconds / 60))
  seconds=$((seconds % 60))
  h=""; m=""; s=""
  if [ ! $hours =  "1" ] ; then h="s"; fi
  if [ ! $minutes =  "1" ] ; then m="s"; fi
  if [ ! $seconds =  "1" ] ; then s="s"; fi

  if [ ! $hours =  0 ] ; then echo "Completed in $hours hour$h, $minutes minute$m and $seconds second$s"
  elif [ ! $minutes = 0 ] ; then echo "Completed in $minutes minute$m and $seconds second$s"
  else echo "Completed in $seconds second$s"; fi
}

nginx_start ()
{
  # Create a nginx container hosting software download locally

  # Check if we already have this container in status exited
  STATUS="$($DOCKER_CMD inspect --format "{{ .State.Status }}" $SOFTWARE_CONTAINER 2>/dev/null)"

  if [ -z "$STATUS" ]; then
    echo "Creating Docker container: $SOFTWARE_CONTAINER"
    $DOCKER_CMD run --name $SOFTWARE_CONTAINER -p $SOFTWARE_PORT:80 -v $SOFTWARE_DIR:/usr/share/nginx/html:ro -d nginx
  elif [ "$STATUS" = "exited" ]; then
    echo "Starting existing Docker container: $SOFTWARE_CONTAINER"
    $DOCKER_CMD start $SOFTWARE_CONTAINER
  fi

  echo "Starting Docker container: $SOFTWARE_CONTAINER"
  # Start local nginx container to host SW Repository
  SOFTWARE_REPO_IP="$($DOCKER_CMD inspect --format "{{ .NetworkSettings.IPAddress }}" $SOFTWARE_CONTAINER 2>/dev/null)"
  if [ -z "$SOFTWARE_REPO_IP" ]; then
    echo "Unable to locate software repository."
  else
    DOWNLOAD_FROM=http://$SOFTWARE_REPO_IP
    echo "Hosting IBM Software repository on $DOWNLOAD_FROM"
  fi
  echo
}

nginx_stop ()
{
  # Stop and remove SW repository
  $DOCKER_CMD stop $SOFTWARE_CONTAINER
  $DOCKER_CMD container rm $SOFTWARE_CONTAINER
  echo "Stopped & Removed Software Repository Container"
  echo
}

docker_show_status ()
{
  if [ -z "$DOCKER_STATUS" ]; then
   echo "Status: notexisting"
  else    
    echo Status: "$DOCKER_STATUS"
  fi

  return 0
}

docker_status ()
{
  DOCKER_STATUS="$($DOCKER_CMD inspect --format "{{ .State.Status }}" $DOCKER_CONTAINER 2>/dev/null)"
}

docker_inspect_image ()
{
  DOCKER_IMAGE_ID="$($DOCKER_CMD inspect --format "{{.Id}}" $DOCKER_IMAGE 2>/dev/null)"
  DOCKER_IMAGE_SHORTID=`echo $DOCKER_IMAGE_ID | cut -d":" -f2 | cut -c1-12`

  if [ -z "$1" ]; then return 0; fi

  DOCKER_IMAGE_VERSION="$($DOCKER_CMD inspect --format "{{ .Config.Labels.version }}" $DOCKER_IMAGE 2>/dev/null)"
  DOCKER_IMAGE_BUILDTIME="$($DOCKER_CMD inspect --format "{{ .Config.Labels.buildtime }}" $DOCKER_IMAGE 2>/dev/null)" 
  DOCKER_IMAGE_SIZE="$($DOCKER_CMD inspect --format "{{.Size}}" $DOCKER_IMAGE 2>/dev/null)" 

  if [ -z "$DOCKER_IMAGE_SIZE" ]; then
    DOCKER_IMAGE_SIZE_MB=0
  else
    DOCKER_IMAGE_SIZE_MB=$(($DOCKER_IMAGE_SIZE / 1000 / 1000 )) 
  fi

  DOCKER_IMAGE_DOMINODOCKER_VERSION="$($DOCKER_CMD inspect --format "{{ index .Config.Labels \"DominoDocker.version\" }}" $DOCKER_IMAGE 2>/dev/null)" 
  DOCKER_IMAGE_TRAVELERDOCKER_VERSION="$($DOCKER_CMD inspect --format "{{ index .Config.Labels \"TravelerDocker.version\" }}" $DOCKER_IMAGE 2>/dev/null)" 

  return 0
}


docker_status ()
{
  DOCKER_STATUS="$($DOCKER_CMD inspect --format "{{ .State.Status }}" $DOCKER_CONTAINER 2>/dev/null)"
  if [ -z "$DOCKER_STATUS" ]; then return 0; fi
}

docker_inspect_container ()
{
  DOCKER_STATUS="$($DOCKER_CMD inspect --format "{{ .State.Status }}" $DOCKER_CONTAINER 2>/dev/null)"
  DOCKER_CONTAINER_VERSION="$($DOCKER_CMD inspect --format "{{ .Config.Labels.version }}" $DOCKER_CONTAINER 2>/dev/null)"
  if [ -z "$DOCKER_STATUS" ]; then return 0; fi

  DOCKER_CONTAINER_IMAGE_ID="$($DOCKER_CMD inspect --format "{{ .Image }}" $DOCKER_CONTAINER 2>/dev/null)"
  DOCKER_CONTAINER_ID="$($DOCKER_CMD inspect --format "{{ .Id }}" $DOCKER_CONTAINER 2>/dev/null)"

  DOCKER_CONTAINER_SHORTID=`echo $DOCKER_CONTAINER_ID | cut -d":" -f2 | cut -c1-12`
  DOCKER_CONTAINER_IMAGE_SHORTID=`echo $DOCKER_CONTAINER_IMAGE_ID | cut -d":" -f2 | cut -c1-12`

  if [ -z "$1" ]; then return 0; fi

  DOCKER_CONTAINER_NAME="$($DOCKER_CMD inspect --format "{{ .Name }}" $DOCKER_CONTAINER | cut -d/ -f2 2>/dev/null)"
  DOCKER_CONTAINER_IMAGE="$($DOCKER_CMD inspect --format "{{ .Config.Image }}" $DOCKER_CONTAINER 2>/dev/null)"

  DOCKER_CONTAINER_HOSTNAME="$($DOCKER_CMD inspect --format "{{ .Config.Hostname }}" $DOCKER_CONTAINER 2>/dev/null)"
  DOCKER_CONTAINER_DRIVER="$($DOCKER_CMD inspect --format "{{ .Driver }}" $DOCKER_CONTAINER 2>/dev/null)"
  DOCKER_CONTAINER_PLATFORM="$($DOCKER_CMD inspect --format "{{ .Platform }}" $DOCKER_CONTAINER 2>/dev/null)"


  DOCKER_CONTAINER_NETWORKMODE="$($DOCKER_CMD inspect --format "{{ .HostConfig.NetworkMode }}" $DOCKER_CONTAINER 2>/dev/null)"

  if [ -z "$DOCKER_NETWORK_NAME" ]; then
    DOCKER_CONTAINER_IPADDRESS="$($DOCKER_CMD inspect --format "{{ .NetworkSettings.IPAddress }}" $DOCKER_CONTAINER 2>/dev/null)"
  else
    DOCKER_CONTAINER_IPADDRESS="$($DOCKER_CMD inspect --format "{{ .NetworkSettings.Networks.$DOCKER_NETWORK_NAME.IPAddress }}" $DOCKER_CONTAINER 2>/dev/null)"
  fi

  if [ "$DOCKER_CONTAINER_IPADDRESS" = "<no value>" ]; then
    DOCKER_CONTAINER_IPADDRESS=
  fi

  DOCKER_CONTAINER_BUILDTIME="$($DOCKER_CMD inspect --format "{{ .Config.Labels.buildtime }}" $DOCKER_CONTAINER 2>/dev/null)"
  DOCKER_CONTAINER_VOLUMES="$($DOCKER_CMD inspect --format '{{range .Mounts}} {{ .Source }} {{end}}' $DOCKER_CONTAINER | xargs 2>/dev/null)"
  DOCKER_CONTAINER_MOUNTS="$($DOCKER_CMD inspect --format '{{range .Mounts}} {{ .Destination }} {{end}}' $DOCKER_CONTAINER | xargs 2>/dev/null)"
  DOCKER_CONTAINER_HEALTH="$($DOCKER_CMD inspect --format "{{ .State.Health.Status }}" $DOCKER_CONTAINER 2>/dev/null)"

  DOCKER_CONTAINER_DOMINODOCKER_VERSION="$($DOCKER_CMD inspect --format "{{ index .Config.Labels \"DominoDocker.version\" }}" $DOCKER_CONTAINER 2>/dev/null)"
  DOCKER_CONTAINER_TRAVELERDOCKER_VERSION="$($DOCKER_CMD inspect --format "{{ index .Config.Labels \"TravelerDocker.version\" }}" $DOCKER_CONTAINER 2>/dev/null)" 

  STARTDATE="$($DOCKER_CMD inspect --format "{{ .State.StartedAt }}" $DOCKER_CONTAINER | cut -f1 -d+ 2>/dev/null)"
  DOCKER_CONTAINER_STARTED_AT=`date +"%d.%m.%Y %H:%M:%S" -d "$STARTDATE"`

  return 0
}

docker_inspect_extras ()
{
  if [ -z "$1" ]; then return 0; fi

  if [ "$DOCKER_STATUS" = "running" ]; then 
    # DOCKER_CONTAINER_OS_VERSION=`$DOCKER_CMD exec -it $DOCKER_CONTAINER cat /etc/redhat-release`
    # DOCKER_CONTAINER_OS_KERNEL=`$DOCKER_CMD exec -it $DOCKER_CONTAINER uname -r`
    DOCKER_CONTAINER_DOMINO_REV=`$DOCKER_CMD exec -it $DOCKER_CONTAINER cat /opt/ibm/domino/.install.dat | awk -F '(=| =)' -v SEARCH_STR="rev" '{if (tolower($1) == tolower(SEARCH_STR)) print $2}' | cut -d'"' -f2`
  fi
}

docker_show_infos ()
{
  if [ -z "$DOCKER_STATUS" ]; then
    if [ -z "$DOCKER_IMAGE_ID" ]; then
      echo "Docker container and image not found"
      return 0
    else
      echo "Docker container not found"
    fi
    #return 0
  fi

  docker_inspect_image
  docker_inspect_container
  docker_inspect_extras

  print_delim
  echo " Status        :  $DOCKER_STATUS"

  if [ "$DOCKER_IMAGE_VERSION" = "$DOCKER_CONTAINER_VERSION" ]; then
    echo " Version       :  $DOCKER_IMAGE_VERSION"
  else
    echo " Version CNT   :  $DOCKER_CONTAINER_VERSION"
    echo " Version IMG   :  $DOCKER_IMAGE_VERSION"
  fi

  echo " Container ID  :  $DOCKER_CONTAINER_SHORTID"
  if [ "$DOCKER_IMAGE_ID" = "$DOCKER_CONTAINER_IMAGE_ID" ]; then
    echo " Image-ID      :  $DOCKER_IMAGE_SHORTID"
  else
    echo " Image-ID CNT  :  $DOCKER_CONTAINER_IMAGE_SHORTID"
    echo " Image-ID IMG  :  $DOCKER_IMAGE_SHORTID"
  fi
  
  print_delim

  return 0
}


docker_show_inspect ()
{
  if [ -z "$DOCKER_STATUS" ]; then 
    if [ -z "$DOCKER_IMAGE_ID" ]; then 
      echo "Docker container and image not found"
      return 0
    else
      echo "Docker container not found"
    fi
    #return 0
  fi

  docker_inspect_image "$1" 
  docker_inspect_container "$1" 
  docker_inspect_extras "$1"

  print_delim
  echo " Status         :  $DOCKER_STATUS"
  echo " Health         :  $DOCKER_CONTAINER_HEALTH"
  echo " Started        :  $DOCKER_CONTAINER_STARTED_AT"
  echo " Name           :  $DOCKER_CONTAINER_NAME"
  echo " Image          :  $DOCKER_CONTAINER_IMAGE"

  if [ "$DOCKER_IMAGE_VERSION" = "$DOCKER_CONTAINER_VERSION" ]; then 
    echo " Version        :  $DOCKER_IMAGE_VERSION"
  else
    echo " Version CNT    :  $DOCKER_CONTAINER_VERSION"
    echo " Version IMG    :  $DOCKER_IMAGE_VERSION"
  fi

  echo " Image Size     :  $DOCKER_IMAGE_SIZE_MB MB" 
  echo

  
  if [ "$DOCKER_CONTAINER_DOMINODOCKER_VERSION" = "$DOCKER_IMAGE_DOMINODOCKER_VERSION" ]; then 
    echo " Domino Ver     :  $DOCKER_CONTAINER_DOMINODOCKER_VERSION"
  else
    echo " Domino Ver CNT :  $DOCKER_CONTAINER_DOMINODOCKER_VERSION"
    echo " Domino Ver IMG :  $DOCKER_IMAGE_DOMINODOCKER_VERSION"
  fi

  if [ "$DOCKER_IMAGE_BUILDTIME" = "$DOCKER_CONTAINER_BUILDTIME" ]; then 
    echo " BuildTime      :  $DOCKER_IMAGE_BUILDTIME"
  else
    echo " BuildTime CNT  :  $DOCKER_CONTAINER_BUILDTIME"
    echo " BuildTime IMG  :  $DOCKER_IMAGE_BUILDTIME"
  fi
  
  if [ ! -z "$DOCKER_CONTAINER_IMAGE_ID" ]; then

    echo
    echo " Hostname       :  $DOCKER_CONTAINER_HOSTNAME"
    echo " Volumes        :  $DOCKER_CONTAINER_VOLUMES"
    echo " Mounts         :  $DOCKER_CONTAINER_MOUNTS"
    echo " NetworkMode    :  $DOCKER_CONTAINER_NETWORKMODE"
    echo " IPAddress      :  $DOCKER_CONTAINER_ADDRESS"
    echo
    echo " Platform       :  $DOCKER_CONTAINER_PLATFORM"
    echo " Driver         :  $DOCKER_CONTAINER_DRIVER"
    # echo " Container OS   :  $DOCKER_CONTAINER_OS_VERSION"
    # echo " Kernel         :  $DOCKER_CONTAINER_OS_KERNEL"
  fi

  print_delim

  echo " Container ID   :  $DOCKER_CONTAINER_SHORTID"
  if [ "$DOCKER_IMAGE_ID" = "$DOCKER_CONTAINER_IMAGE_ID" ]; then 
    echo " Image-ID       :  $DOCKER_IMAGE_SHORTID"
  else
    echo " Image-ID CNT   :  $DOCKER_CONTAINER_IMAGE_SHORTID"
    echo " Image-ID IMG   :  $DOCKER_IMAGE_SHORTID"
  fi

  print_delim

  if [ ! -z "$DOCKER_CONTAINER_IMAGE_ID" ]; then

    DOCKER_PORTS=`$DOCKER_CMD port "$DOCKER_CONTAINER"`    

    echo " Docker Ports   :"
    if [ ! -z "$DOCKER_PORTS" ]; then
      echo "$DOCKER_PORTS" | awk '{print "                  " $0}'
      print_delim
    fi
  fi

}

docker_start ()
{
  if [ -z "$DOCKER_STATUS" ]; then echo "Container [$DOCKER_CONTAINER] does not exist"; return 1; fi
  if [ "$DOCKER_STATUS" = "running" ]; then echo "Container [$DOCKER_CONTAINER] already started"; return 1; fi

  if [ "$PARAM2" = "live" ]; then
    DOCKER_IT="-ia"
  elif [ "$PARAM2" = "it" ]; then
    DOCKER_IT="-ia"
  else
    DOCKER_IT=""
  fi

  if [ ! -z "$DOCKER_IT" ]; then
    echo "--- Starting Docker Container interactive [ Use Ctrl + p q to exit ] ---"
    echo
  fi

  $DOCKER_CMD start $DOCKER_IT $DOCKER_CONTAINER
 
  return 0
}

docker_stop ()
{
  if [ -z "$DOCKER_STATUS" ]; then echo "Container [$DOCKER_CONTAINER] does not exist"; return 1; fi
  if [ "$DOCKER_STATUS" = "exited" ]; then echo "Container [$DOCKER_CONTAINER] already stopped"; return 1; fi

  if [ "$PARAM2" = "live" ]; then
    $DOCKER_CMD attach $DOCKER_CONTAINER --no-stdin &
  fi

  $DOCKER_CMD stop --time=$DOMINO_SHUTDOWN_TIMEOUT $DOCKER_CONTAINER
}

docker_logs ()
{
  if [ -z "$DOCKER_STATUS" ]; then echo "Container [$DOCKER_CONTAINER] does not exist"; return 1; fi

  echo "--- [BEGIN - $DOCKER_CONTAINER - BEGIN] ---"
  echo
  $DOCKER_CMD logs $DOCKER_CONTAINER
  echo
  echo "--- [END - $DOCKER_CONTAINER - END] ---"

  return 0
}


docker_build ()
{
  if [ -z "$DOCKER_FILE" ]; then
    echo "No dockerfile specified in config file."
    echo "If you would like to build a custom image please provide a dockerfile name"
    echo "otherwise the default image is being used to 'run' a container"
    return 0
  fi

  if [ -z "$DOCKER_IMAGE_NAMEVERSION" ]; then
    echo "No target image defined."
    return 0
  fi

  echo "Building Image : " $IMAGENAME

  if [ "$SOFTWARE_USE_NGINX" = "1" ]; then
    nginx_start
  fi

  $DOCKER_CMD build --no-cache --label "version"="$DOCKER_IMAGE_BUILD_VERSION" --label "buildtime"="$BUILDTIME" --label "release-date"="$DOCKER_IMAGE_RELEASE_DATE" -t $DOCKER_IMAGE_NAMEVERSION $DOCKER_TAG_LATEST_CMD -f $DOCKER_FILE --build-arg "DownloadFrom=$DOWNLOAD_FROM" --build-arg LinuxYumUpdate=$LinuxYumUpdate --build-arg "SPECIAL_WGET_ARGUMENTS=$SPECIAL_WGET_ARGUMENTS" .
  echo

  if [ "$SOFTWARE_USE_NGINX" = "1" ]; then
    nginx_stop
  fi

  print_runtime
  echo

  return 0
}

docker_run ()
{
  if [ ! -z "$DOCKER_STATUS" ]; then echo "Container [$DOCKER_CONTAINER] already exists [status: $DOCKER_STATUS]"; return 1; fi

  if [ -z "$DOCKER_IMAGE_ID" ]; then
    if [ "$1" = "force" ]; then
      echo [FORCE-MODE] Building image first ...
      echo 
      docker_build
      echo
      echo [FORCE-MODE] Built image before run
      echo 

    else
      echo "Image [$DOCKER_IMAGE] does not exist - please build image first"
      return 1
    fi
  fi

  if [ "$PARAM1" = "runit" ]; then
    DOCKER_IT="yes"
  elif [ "$PARAM2" = "live" ]; then
    DOCKER_IT="yes"
  elif [ "$PARAM2" = "it" ]; then
    DOCKER_IT="yes"
  else
    DOCKER_IT=""
  fi

  if [ ! -z "$DOCKER_IT" ]; then
    echo "--- Running Docker Container interactive [ Use Ctrl + p q to exit ] ---"
    echo
    DOCKER_IT="-it"
  else
    DOCKER_IT="-d -it"
  fi


  if [ -z "$DOCKER_NETWORK" ]; then
   
    if [ ! -z "$DOCKER_NETWORK_NAME" ]; then
      DOCKER_NETWORK="--network=$DOCKER_NETWORK_NAME"       
    fi
  fi

  if [ ! -z "$DOCKER_FULL_ENV_FILE" ]; then
    DOCKER_ENV_FILE_OPTION="--env-file $DOCKER_FULL_ENV_FILE"
   
    if [ ! -r "$DOCKER_FULL_ENV_FILE" ]; then
      echo "Error - Cannot read environment file [$DOCKER_FULL_ENV_FILE]"
      exit 1
    fi

  fi

  if [ ! -z "$DOCKER_NOTES_UID" ]; then
    DOCKER_NOTES_UID_OPTION="--user $DOCKER_NOTES_UID"
  fi

  $DOCKER_CMD run $DOCKER_IT $DOCKER_PORTS --hostname=$DOCKER_HOSTNAME --name $DOCKER_CONTAINER $DOCKER_NETWORK $DOCKER_ENV_FILE_OPTION --stop-timeout=$DOMINO_SHUTDOWN_TIMEOUT --cap-add=SYS_PTRACE $DOCKER_VOLUMES $DOCKER_SPECIAL_OPTIONS $DOCKER_NOTES_UID_OPTION $DOCKER_IMAGE

  return 0
}

docker_remove ()
{
  if [ -z "$DOCKER_STATUS" ]; then echo "Container [$DOCKER_CONTAINER] does not exist"; return 1; fi

  if [ "$DOCKER_STATUS" = "running" ]; then 
   
    if [ "$1" = "force" ]; then
      echo [FORCE-MODE] Stopping running container first ...
      docker_stop 
    else
      echo "Container [$DOCKER_CONTAINER] is started -- cannot remove a running container";
      return 1
    fi
  fi

  $DOCKER_CMD rm $DOCKER_CONTAINER	
  return 0
}

docker_removeimage ()
{
  if [ -z "$DOCKER_IMAGE_ID" ]; then echo "Image [$DOCKER_IMAGE] does not exist"; return 1; fi

  if [ ! -z "$DOCKER_STATUS" ]; then

    if [ "$1" = "force" ]; then
       echo [FORCE-MODE] Removing container first ...
       docker_remove $1
    else
      echo "Container [$DOCKER_CONTAINER] still exists - cannot remove image"
      return 1
    fi
  fi

  # if configured remove latest tag first
  if [ ! -z "$DOCKER_TAG_LATEST" ]; then
    $DOCKER_CMD rmi "$DOCKER_TAG_LATEST"
  fi 

  $DOCKER_CMD rmi "$DOCKER_IMAGE_NAMEVERSION"

  return 0
}

docker_attach ()
{
  if [ -z "$DOCKER_STATUS" ]; then echo "Container [$DOCKER_CONTAINER] does not exist"; return 1; fi
  if [ ! "$DOCKER_STATUS" = "running" ]; then echo "Container [$DOCKER_CONTAINER] not started"; return 1; fi

  echo "--- Attaching to Docker Container [ Use Ctrl + p q to exit ] ---"
  echo
  $DOCKER_CMD attach $DOCKER_CONTAINER

  return 0
}

docker_attach ()
{
  if [ -z "$DOCKER_STATUS" ]; then echo "Container [$DOCKER_CONTAINER] does not exist"; return 1; fi
  if [ ! "$DOCKER_STATUS" = "running" ]; then echo "Container [$DOCKER_CONTAINER] not started"; return 1; fi

  echo "--- Attaching to Docker Container [ Use Ctrl + p q to exit ] ---"
  echo
  $DOCKER_CMD attach $DOCKER_CONTAINER

  return 0
}

docker_update ()
{
  if [ -z "$DOCKER_STATUS" ]; then echo "Container [$DOCKER_CONTAINER] does not exist"; return 1; fi

  if [ "$DOCKER_CONTAINER_IMAGE_ID" = "$DOCKER_IMAGE_ID" ]; then
    echo "Image did not change -- No Update needed"
    return 0 
  fi
 
  echo "Updating Container [$DOCKER_CONTAINER] ..."
   
  if [ "$DOCKER_STATUS" = "running" ]; then 
    echo "Stopping Container [$DOCKER_CONTAINER] before update ..."
    docker_stop
  fi

  docker_inspect_container

  echo "Removing Container [$DOCKER_CONTAINER] ..."
  docker_remove
  
  echo "Creating & starting new Container [$DOCKER_CONTAINER] ..."
  docker_inspect_container
  docker_run
  docker_inspect_container
  
  echo
  if [ "$DOCKER_CONTAINER_IMAGE_ID" = "$DOCKER_IMAGE_ID" ]; then
    echo "Successfully updated Container [$DOCKER_CONTAINER]"
    return 0
  else
    echo "Failed to updated Container [$DOCKER_CONTAINER]"
    return 1
  fi
}

docker_bash ()
{
  if [ -z "$DOCKER_STATUS" ]; then echo "Container [$DOCKER_CONTAINER] does not exist"; return 1; fi
  if [ ! "$DOCKER_STATUS" = "running" ]; then echo "Container [$DOCKER_CONTAINER] not started"; return 1; fi

  echo "--- Starting bash in Docker [ Use exit to return ] ---"
  echo

  if [ "$1" = "root" ]; then
    $DOCKER_CMD exec -it --user 0 $DOCKER_CONTAINER /bin/bash
  else
    $DOCKER_CMD exec -it $DOCKER_CONTAINER /bin/bash
  fi

  return 0
}

show_version ()
{
  echo "Nash!Com Docker Script Version $DOCKER_SCRIPT_VERSION"
  echo "(Running on $DOCKER_ENV_NAME Version $DOCKER_VERSION)" 
  return 0
}

usage ()
{
  show_version
  echo
  echo "Usage: $SCRIPT_NAME { build | run | start | stop | status | inspect | logs | attach | domino | bash | remove | removeimage | update | config | env | cpcfg | cpenv | port | version | help}"

  return 0
}

help ()
{
  usage
  echo
  echo "build           builds a current image -- even image tags might not have changed to ensure OS patches are installed"
  echo "run   [live]    runs a container -- will initiate a container if not present ('live' shows start script output, alias 'runit')"
  echo "start [live]    start an existing container (the 'live' option shows start script output)"
  echo "stop  [live]    stops container (the 'live' option shows start script output)"
  echo "status          shows container status (running, exited, notexisting)"
  echo "info            shows status and basic information about container and image"
  echo "inspect         shows detailed information about container and image"
  echo "logs            shows container logs (output from entry point script/start script)"
  echo "attach          attach to entry point script"
  echo "domino          pass a command to start script (e.g. domino nsd)"
  echo "bash [root]     invokes a bash in the running container. optionally run as root instead of notes user"
  echo "remove|rm       removes the container (if not running)"
  echo "removeimage|rmi removes the current container (you have to remove the container first)"
  echo "update          updates the container if referenced image has changed (stops Domino, stops the container, runs a new image)"
  echo "port            show used tcp/ip ports for container"
  echo "config|cfg      edit configuration"
  echo "env             edit environment file"
  echo "cpcfg           copy configuration file to config directory"
  echo "cpenv           copy environment filei to config directory"
  echo "version         shows script version information"
  echo "help            you already figured out what help does ;-)"

  return 0
}

docker_domino_cmd ()
{
  if [ -z "$1" ]; then
    echo "No command specified!"
    return 0
  fi
  
  $DOCKER_CMD exec -it $DOCKER_CONTAINER "$1" "$2" "$3" "$4" "$5" "$6"

  return 0
}

copy_config_file()
{
  if [ ! -e "$DOMINO_DOCKER_CFG_DIR" ]; then
    echo "No config directory configued"
    return 0
  fi

  NEW_CONFIG_FILE=$DOMINO_DOCKER_CFG_DIR/config_`basename $SCRIPT_NAME | awk -F "docker_" '{print $2}'`
  if [ -e "$NEW_CONFIG_FILE" ]; then
    if [ "$1" = "force" ]; then
      echo "Overwriting Config File [$NEW_CONFIG_FILE]"
      rm -f "$NEW_CONFIG_FILE"
    else
      echo "Config File [$NEW_CONFIG_FILE] already exists!"
      return 0
    fi
  fi

  CONFIG_TEMPLATE_FILE=$FULL_SCRIPT_DIR_NAME/config_`basename $SCRIPT_NAME | awk -F "docker_" '{print $2}'`

  if [ -e "$CONFIG_TEMPLATE_FILE" ]; then
    echo "New config file [$CONFIG_TEMPLATE_FILE] -> [$NEW_CONFIG_FILE]"

    mkdir -p "$DOMINO_DOCKER_CFG_DIR"
    cp "$CONFIG_TEMPLATE_FILE" "$NEW_CONFIG_FILE" 

  else
    echo "Configuration template [$CONFIG_TEMPLATE_FILE] not found - Using default config -> [$NEW_CONFIG_FILE]"
    mkdir -p "$DOMINO_DOCKER_CFG_DIR"
    CONFIG_TEMPLATE_FILE=$FULL_SCRIPT_DIR_NAME/config_domino
    cp "$CONFIG_TEMPLATE_FILE" "$NEW_CONFIG_FILE" 
  fi
}

copy_env_file()
{
  if [ ! -e "$DOMINO_DOCKER_CFG_DIR" ]; then
    echo "No config directory configued"
    return 0
  fi

  NEW_ENV_FILE=$DOMINO_DOCKER_CFG_DIR/$DOCKER_ENV_FILE
  if [ -e "$NEW_ENV_FILE" ]; then
    if [ "$1" = "force" ]; then
      echo "Overwriting Domino Environment File [$NEW_ENV_FILE]"
      rm -f "$NEW_ENV_FILE"
    else
      echo "Domino Environment File [$NEW_ENV_FILE] already exists!"
      return 0
    fi
  fi

  ENV_TEMPLATE_FILE=$FULL_SCRIPT_DIR_NAME/$DOCKER_ENV_FILE

  if [ -e "$ENV_TEMPLATE_FILE" ]; then
    echo "New config file $ENV_TEMPLATE_FILE -> [$NEW_ENV_FILE]"

    mkdir -p "$DOMINO_DOCKER_CFG_DIR"
    cp "$ENV_TEMPLATE_FILE" "$NEW_ENV_FILE"

  else
    echo "Configuration template [$ENV_TEMPLATE_FILE] not found - Using default config -> [$NEW_ENV_FILE]"
    mkdir -p "$DOMINO_DOCKER_CFG_DIR"
    ENV_TEMPLATE_FILE=$FULL_SCRIPT_DIR_NAME/env_domino
    cp "$ENV_TEMPLATE_FILE" "$NEW_ENV_FILE"
  fi
}

check_docker_environment "$PARAM1"
docker_inspect_image
docker_inspect_container
config_warnings

echo

case "$PARAM1" in
	
  status)
    docker_show_status 
    ;;

  inspect|fullinfo)
    docker_show_inspect full 
    ;;

  info)
    if [ -z "$PARAM2" ]; then
      docker_show_infos
    else
      docker_show_inspect full 
    fi
    ;;

  build)
    docker_build
    ;;

  run|runit)
    docker_run "$PARAM2"
    ;;
	  
  start)

    docker_start
    ;;

  logs|log)
    docker_logs
    ;;

  attach)
    docker_attach
    ;;

  stop)
    docker_stop
    ;;

  bash|shell)
    docker_bash "$PARAM2"
    ;;

  cmd)
    docker_domino_cmd "$PARAM2" "$PARAM3" "$PARAM4" "$PARAM5"
    ;;

  remove|rm)
    docker_remove "$PARAM2"
    ;;

  removeimage|rmi)
    docker_removeimage "$PARAM2"
    ;;

  update)
    docker_update
    ;;

  domino)
    docker_domino_cmd domino "$PARAM2" "$PARAM3" "$PARAM4" "$PARAM5"
    ;;

  port)
   $DOCKER_CMD port "$DOCKER_CONTAINER"
   ;;

  config|cfg)
    $EDIT_COMMAND "$CONFIG_FILE"
    ;;

  cpcfg)
    copy_config_file "$PARAM2"
    ;;

  cpenv)
    copy_env_file "$PARAM2"
    ;;

  env)
    $EDIT_COMMAND "$DOCKER_FULL_ENV_FILE"
    ;;

  dockerfile)
    if [ -z $DOCKER_FILE ]; then
      echo "No dockerfile configured"
    else
      $EDIT_COMMAND $DOCKER_FILE
    fi
    ;;

  version)
    show_version
    ;;

  help)
    help
    ;;

  *)
    if [ -z "$PARAM1" ]; then
      usage 
    else
      echo "Invalid command:" [$PARAM1]
      usage 
    fi
    ;;

esac

echo 
exit 0
